﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.IO;

namespace Voice_Simulator
{
    public partial class Form1 : Form
    {
        public Thread sendding_thread;
        string txtPath = Application.StartupPath;
        public Semaphore sending_sem = new Semaphore(1, 1), nack_sem = new Semaphore(0, 1), recv_sem = new Semaphore(0, 1);
        public string newFileName = "logfile.txt", comport_name = "comport.txt", logfile_path, comport_path, comport_str = "Com13";
        Char[] cmd_id, Rcv_array;
        public string RxString = "", data_input = "", rec_buf = "";
        public Thread newThread, nackproc_thread;
        string out_put = "", ab_output = "";
        public int nack_sendtime = 0;
        bool nack_proc = false, recv_end = false;
        public Form1()
        {
            InitializeComponent();
        }
        private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            rec_buf += serialPort1.ReadExisting();
            if (rec_buf.Length > 1)
            {
                if (rec_buf.Substring(rec_buf.Length - 1, 1) == "\r" || rec_buf.Substring(rec_buf.Length - 2, 1) == "\r")
                {
                    RxString = rec_buf; rec_buf = "";
                    Rcv_array = RxString.ToCharArray();
                    if (radioButton6.Checked)
                    {
                        serialPort1.Close();
                        System.IO.File.AppendAllText(logfile_path, DateTime.Now.ToLongTimeString() + ":Disconnect 3\r\n");
                        this.Invoke((MethodInvoker)delegate()
                        {
                            //textBox1.AppendText("\r\n");
                            button2.Enabled = true;
                        });
                        try
                        {
                            recv_sem.Release();
                        }
                        catch
                        {
                        }
                        recv_end = false;
                        return;
                    }
                    else
                        this.Invoke(new EventHandler(DisplayText), "");
                }
            }
        }

        private void DisplayText(object sender, EventArgs e)
        {
            if (radioButton6.Checked)
            {
                serialPort1.Close();
                System.IO.File.AppendAllText(logfile_path, DateTime.Now.ToLongTimeString() + ":Disconnect 3\r\n");
                this.Invoke((MethodInvoker)delegate()
                {
                    //textBox1.AppendText("\r\n");
                    button2.Enabled = true;
                });
                try
                {
                    recv_sem.Release();
                }
                catch
                {
                }
                recv_end = false;
                return;
            }
            string s = "";
            for (int cnt = 0; cnt < Rcv_array.Length; cnt++)
            {
                if (Rcv_array[cnt] < 32 || Rcv_array[cnt] > 126)
                    s += Convert.ToInt32(Rcv_array[cnt]).ToString("x2").ToUpper();
                else
                    s += Rcv_array[cnt];
            }
            if (Rcv_array[Rcv_array.Length - 1] == 10)
                s += "\r\n";
            else if (Rcv_array[Rcv_array.Length - 1] == 13)
                s += "\r\n";

            sending_sem.WaitOne();
            textBox1.SelectionStart = textBox1.TextLength;
            textBox1.SelectionLength = 0;
            textBox1.SelectionColor = Color.Red;
            s = DateTime.Now.ToLongTimeString() + ":" + s;
            textBox1.AppendText(s);
            textBox1.SelectionColor = textBox1.ForeColor;
            System.IO.File.AppendAllText(logfile_path, s);
            if (textBox1.Text.Length >= 32000)
                textBox1.Text = "";
            textBox1.SelectionStart = textBox1.Text.Length;
            textBox1.ScrollToCaret();
            try
            {
                sending_sem.Release();
            }
            catch { }
            if (nack_proc)
            {
                try
                {
                    nack_sem.Release();
                }
                catch { }
            }
            else if (Rcv_array[3] == '?')
            {
                nackproc_thread = new Thread(nack_processing);
                nackproc_thread.Start();
            }
            else if (recv_end)
            {
                try
                {
                    recv_sem.Release();
                }
                catch { }
                recv_end = false;
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            char a = (char)0x10;
            Char[] data_array = data_input.ToCharArray();
            cmd_id = ((int)numericUpDown1.Value).ToString("x2").ToCharArray();
            out_put = "";
            out_put += a;
            out_put += ((int)numericUpDown1.Value).ToString("x2").ToUpper();
            int checksum, ab_checksum;
            checksum = cmd_id[0];
            checksum += cmd_id[1];
            if (radioButton7.Checked)
            {
                nack_sendtime = 0;
            }
            else if (radioButton8.Checked)
            {
                nack_sendtime = 1;
            }
            else if (radioButton9.Checked)
            {
                nack_sendtime = 2;
            }
            else if (radioButton10.Checked)
            {
                nack_sendtime = 3;
            }
            foreach (char element in data_array)
            {
                out_put += element;
                checksum += element;
            }
            ab_checksum = checksum + 2;
            checksum %= 0x100;
            ab_checksum %= 0x100;
            ab_output = out_put;
            out_put += checksum.ToString("x2").ToUpper();
            ab_output += ab_checksum.ToString("x2").ToUpper();
            if (comboBox1.Text == "1")
            {
                out_put += "\r";
                ab_output += "\r";
            }
            else
            {
                out_put += "\r\n";
                ab_output += "\r\n";
            }
            if (!serialPort1.IsOpen)
            {
                try
                {
                    StreamReader file = System.IO.File.OpenText(comport_path);
                    serialPort1.PortName = file.ReadLine();
                    serialPort1.BaudRate = Convert.ToInt32(file.ReadLine());
                    serialPort1.DataBits = Convert.ToInt32(file.ReadLine());

                    serialPort1.Encoding = Encoding.GetEncoding(28591);
                    switch (file.ReadLine())
                    {
                        case "0":
                            serialPort1.StopBits = System.IO.Ports.StopBits.None;
                            break;
                        case "1":
                            serialPort1.StopBits = System.IO.Ports.StopBits.One;
                            break;
                        case "1.5":
                            serialPort1.StopBits = System.IO.Ports.StopBits.OnePointFive;
                            break;
                        case "2":
                            serialPort1.StopBits = System.IO.Ports.StopBits.Two;
                            break;
                        default:
                            break;
                    } switch (file.ReadLine())
                    {
                        case "None":
                            serialPort1.Parity = System.IO.Ports.Parity.None;
                            break;
                        case "Even":
                            serialPort1.Parity = System.IO.Ports.Parity.Even;
                            break;
                        case "Old":
                            serialPort1.Parity = System.IO.Ports.Parity.Odd;
                            break;
                        default:
                            break;
                    }
                    try
                    {
                        timer1.Interval = Convert.ToInt32(file.ReadLine());
                    }
                    catch { timer1.Interval = 5000; }
                    serialPort1.Handshake = System.IO.Ports.Handshake.None;
                    serialPort1.ReadTimeout = 4000;
                    serialPort1.WriteTimeout = 4000;
                    serialPort1.Open();
                    if (radioButton3.Checked)
                    {
                        System.IO.File.AppendAllText(logfile_path, DateTime.Now.ToLongTimeString() + ":Connect\r\n");
                    }
                }
                catch
                {
                    comport comport_form = new comport(this);
                    comport_form.ShowDialog();
                    return;
                }
            }
            newThread = new Thread(subthread);
            newThread.Start();
            button2.Enabled = false;
            timer1.Enabled = true;
        }


        public void nack_processing()
        {
            char a = (char)0x10;
            try
            {
                nack_proc = true;
                while (nack_sendtime > 0)
                {
                    sending_sem.WaitOne();
                    serialPort1.Write(ab_output);
                    this.Invoke(new EventHandler(textbox1_Append), DateTime.Now.ToLongTimeString() + ":"
                        + ab_output.Replace("\r", "0D").Replace(a.ToString(), "10").Replace("\n", "0A") + "\r\n");
                    System.IO.File.AppendAllText(logfile_path, DateTime.Now.ToLongTimeString() + ":"
                        + ab_output.Replace("\r", "0D").Replace(a.ToString(), "10").Replace("\n", "0A") + "\r\n");
                    sending_sem.Release();
                    nack_sem.WaitOne();
                    nack_sendtime--;
                }
                sending_sem.WaitOne();
                serialPort1.Write(out_put);
                this.Invoke(new EventHandler(textbox1_Append), DateTime.Now.ToLongTimeString() + ":"
                    + out_put.Replace("\r", "0D").Replace(a.ToString(), "10").Replace("\n", "0A") + "\r\n");
                System.IO.File.AppendAllText(logfile_path, DateTime.Now.ToLongTimeString() + ":"
                    + out_put.Replace("\r", "0D").Replace(a.ToString(), "10").Replace("\n", "0A") + "\r\n");
                sending_sem.Release();
                nack_sem.WaitOne();
                nack_sendtime--;
                nack_proc = false;
                recv_sem.Release();
                recv_end = false;

            }
            catch (ThreadInterruptedException)
            {
                return;
            }
        }

        public void Rcv_Append()
        {
            char a = (char)0x10;
            sending_sem.WaitOne();
            if (serialPort1.IsOpen == true)
                try
                {
                    string output;
                    if (radioButton1.Checked)
                        output = out_put;
                    else
                    {
                        output = ab_output;
                    }
                    serialPort1.Write(output.Substring(0, output.Length - 1));
                    this.Invoke(new EventHandler(textbox1_Append), DateTime.Now.ToLongTimeString() + ":"
                        + out_put.Substring(0, output.Length - 1).Replace("\r", "0D").Replace(a.ToString(), "10").Replace("\n", "0A"));
                    System.IO.File.AppendAllText(logfile_path, DateTime.Now.ToLongTimeString() + ":"
                        + output.Substring(0, output.Length - 1).Replace("\r", "0D").Replace(a.ToString(), "10").Replace("\n", "0A"));
                    if (radioButton5.Checked)
                    {
                        serialPort1.Close();
                        System.IO.File.AppendAllText(logfile_path, "\r\n" + DateTime.Now.ToLongTimeString() + ":Disconnect 2\r\n");
                        this.Invoke((MethodInvoker)delegate()
                        {
                            textBox1.AppendText("\r\n");
                            button2.Enabled = true;
                        });
                        sending_sem.Release();
                        recv_end = false;
                        return;
                    }
                    serialPort1.Write(output.Substring(output.Length - 1, 1));
                    this.Invoke(new EventHandler(textbox1_Append), out_put.Substring(output.Length - 1, 1).Replace("\r", "0D").Replace(a.ToString(), "10")
                        .Replace("\n", "0A") + "\r\n");
                    System.IO.File.AppendAllText(logfile_path, output.Substring(output.Length - 1, 1).Replace("\r", "0D")
                        .Replace(a.ToString(), "10").Replace("\n", "0A") + "\r\n");
                }
                catch (Exception)
                {
                    this.Invoke(new EventHandler(textbox1_Append), "Com port Error");
                }
            try
            {
                sending_sem.Release();
            }
            catch { }
            if (radioButton4.Checked)
            {
                serialPort1.Close();
                System.IO.File.AppendAllText(logfile_path, DateTime.Now.ToLongTimeString() + ":Disconnect 1\r\n");
                this.Invoke((MethodInvoker)delegate()
                {
                    button2.Enabled = true;
                });
                return;
            }
            recv_end = true;
            recv_sem.WaitOne();
            this.Invoke((MethodInvoker)delegate()
            {
                button2.Enabled = true;
            });

        }

        public void textbox1_Append(object sender, EventArgs e)
        {
            textBox1.AppendText(sender.ToString());
            if (textBox1.Text.Length >= 32000)
                textBox1.AppendText("");
            textBox1.SelectionStart = textBox1.Text.Length;
            textBox1.ScrollToCaret();
        }

        public void subthread()
        {
            try
            {
                Rcv_Append();
            }
            catch (ThreadInterruptedException)
            {
                return;
            }

        }

        private void Form1_Load(object sender, EventArgs e)
        {
            System.Diagnostics.Process MY = System.Diagnostics.Process.GetCurrentProcess();
            MY.PriorityClass = System.Diagnostics.ProcessPriorityClass.High;
            logfile_path = System.IO.Path.Combine(txtPath, newFileName);
            comport_path = System.IO.Path.Combine(txtPath, comport_name);
            comboBox1.SelectedIndex = 0;
            System.IO.File.WriteAllText(logfile_path, "");
            if (System.IO.File.Exists(comport_path))
            {
                comport_str = System.IO.File.ReadAllText(comport_path);
            }
            else
            {
                comport comport_form = new comport(this);
                comport_form.ShowDialog();
            }
        }

        private void label24_Click(object sender, EventArgs e)
        {

        }

        private void button4_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void _TextChanged(object sender, EventArgs e)
        {
        }

        private void richTextBox1_TextChanged(object sender, EventArgs e)
        {
            textBox1.Text = "";
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {

        }

        private void label3_Click(object sender, EventArgs e)
        {

        }

        private void radioButton5_CheckedChanged(object sender, EventArgs e)
        {

        }

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void button5_Click(object sender, EventArgs e)
        {
            openFileDialog1.ShowDialog();
            comboBox2.Text = openFileDialog1.FileName;
            try
            {
                data_input = System.IO.File.ReadAllText(comboBox2.Text);
            }
            catch { }
        }

        private void comboBox2_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {

        }

        private void radioButton1_CheckedChanged(object sender, EventArgs e)
        {

        }

        private void radioButton2_CheckedChanged(object sender, EventArgs e)
        {

        }

        private void radioButton7_CheckedChanged(object sender, EventArgs e)
        {

        }

        private void radioButton10_CheckedChanged(object sender, EventArgs e)
        {

        }
        private void form1_Closed(object sender, FormClosingEventArgs e)
        {
            try
            {
                newThread.Interrupt();
            }
            catch { }
            try
            {
                nackproc_thread.Interrupt();
            }
            catch { }
        }

        private void radioButton3_CheckedChanged(object sender, EventArgs e)
        {

        }

        private void radioButton4_CheckedChanged(object sender, EventArgs e)
        {

        }

        private void radioButton6_CheckedChanged(object sender, EventArgs e)
        {

        }

        private void textBox1_TextChanged_1(object sender, EventArgs e)
        {

        }

        private void numericUpDown1_ValueChanged(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {
            string line_str;
            StreamReader file = System.IO.File.OpenText(comport_path);
            while ((line_str = file.ReadLine()) != null)
            {
                textBox1.Text += line_str;
            }
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            try
            {
                recv_sem.Release();
            }
            catch { }
            timer1.Enabled = false;
            button2.Enabled = true;
        }
    }
}
